<html>
<head><meta charset="utf-8"><title>changes to pre-RFC proposal · project-safe-transmute · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/index.html">project-safe-transmute</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html">changes to pre-RFC proposal</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="183641991"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183641991" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183641991">(Dec 17 2019 at 12:06)</a>:</h4>
<p>I took the time to write out what I believe are the limitations of the pre-RFC proposal: </p>
<ul>
<li>Runtime check required for converting between two types where the type being cast to is not FromAnyBytes but the type being cast from happens to have the same in-memory representation as the type being cast to. For instance, casting between two c-style enums that are technically equivalent to one another.</li>
<li>Runtime performance is fully reliant on a sufficiently smart optimizer (though the optimizer is generally smart enough in reality)</li>
<li>Type level checks even when it's obvious these are not needed (e.g. casting between Foo(u8, u8) and Bar(u16) will require the user to unwrap even though that will never fail). </li>
<li>No ability to directly indicate in the type system that two types can be trivially transmuted between each other (since we always use bytes as the intermediary). </li>
<li>No ability to encode type size constraints at the type level (i.e., we rely on the optimizer to be able to remove these)</li>
</ul>
<p>To address these issues I propose the following changes:</p>
<ul>
<li>Taking a page out of <span class="user-mention" data-user-id="132920">@gnzlbg</span>'s proposal, we replace <code>FromAnyBytes</code> with a general <code>unsafe Compatible&lt;T&gt;</code> trait. All types that would have implemented <code>FromAnyBytes</code> will implement <code>Compatible&lt;[u8]&gt;</code> (the same derive mechanism still exists) . Given that fully taking advantage of <code>Compatible&lt;T&gt;</code> requires changes to the trait system, we don't implement <code>Compatible&lt;T&gt;</code> for anything else yet. In the future as Chalk becomes a thing, we can implement <code>Compatible&lt;T&gt;</code> for more types.</li>
<li><code>ToBytes</code> and <code>FromBytes</code> still exist - these types handle casting types to types that are <code>Compatible</code> _and_ types that can only sometimes be casted to other types if they meet certain runtime conditions.</li>
<li>We leave a <code>safe_transmute</code> API (which is essentially just the infallible version of what we're proposing here) for a future RFC when the needed changes to the trait system are a bit closer to reality.</li>
<li>Additionally, we tie the proposal to const generics and encode size (and alignment when possible) in the type system so that these checks are guaranteed to not happen at runtime. </li>
</ul>
<p>This addresses some of the concerns listed above, though not all, but I believe it leaves things open for those concerns to be addressed in the future in a way that makes sense and is a natural progression of this RFC. </p>
<p>These changes do not _guarantee_ that casts are  zero cost because the API also needs to handle when there is a cost. Though it should be clearer to be people that the optimizer will handle the <code>Compatible</code> case. In the future with chalk, people can move to using <code>safe_transmute</code> if they are casting types that are <code>Compatible</code>. The same goes for the fact that infallible casts need to be <code>unwrap</code>ed, but again these can be move to using the <code>safe_transmute</code> API in the future. Thoughts?</p>



<a name="183642176"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183642176" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183642176">(Dec 17 2019 at 12:09)</a>:</h4>
<blockquote>
<p>All types that would have implemented FromAnyBytes will implement Compatible&lt;u8&gt; (the same derive mechanism still exists) </p>
</blockquote>
<p>Do you mean something like <code>Compatible&lt;[u8]&gt;</code> instead of <code>Compatible&lt;u8&gt;</code> ?</p>



<a name="183642276"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183642276" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183642276">(Dec 17 2019 at 12:11)</a>:</h4>
<p>Yes, sorry. Will fix the typo</p>



<a name="183642571"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183642571" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183642571">(Dec 17 2019 at 12:14)</a>:</h4>
<p>Sounds like a good idea. I think the very first <code>Compatible&lt;T&gt;</code> discussion included an incremental approach to implementing it, that kind of aligns with what you have suggested.</p>



<a name="183642597"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183642597" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183642597">(Dec 17 2019 at 12:15)</a>:</h4>
<p><a href="https://internals.rust-lang.org/t/pre-rfc-frombits-intobits/7071/24" target="_blank" title="https://internals.rust-lang.org/t/pre-rfc-frombits-intobits/7071/24">See this comment</a>:</p>
<blockquote>
<p>A first version could just be this, requiring manual implementation of the trait.</p>
<p>A second version could add compiler support for automatically deriving the trait in addition to doing so manually and for performing transitive closure so that if A: Compatible&lt;B&gt; and B: Compatible&lt;C&gt; (whether manually or automatically), then A: Compatible&lt;C&gt;.</p>
<p>A further addition could be to provide a safe way to manually implement the trait for private types in the current crate.</p>
</blockquote>



<a name="183642712"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183642712" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183642712">(Dec 17 2019 at 12:17)</a>:</h4>
<p>I think that the <code>Compatible&lt;T&gt;</code> design direction most appealing advantage is the transitive closure part, so I'd be wary of stabilizing a less powerful version without at least some nightly prototype supporting transitive closure.</p>



<a name="183642763"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183642763" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183642763">(Dec 17 2019 at 12:18)</a>:</h4>
<p>If when somebody tries to implement this, for whatever reason, we discover that transitive closure is a bad idea, then maybe <code>Compatible&lt;T&gt;</code> isn't worth it and there is a better solution that could be pursued instead.</p>



<a name="183643001"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183643001" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183643001">(Dec 17 2019 at 12:21)</a>:</h4>
<blockquote>
<p>If when somebody tries to implement this, for whatever reason, we discover that transitive closure is a bad idea, then maybe <code>Compatible&lt;T&gt;</code> isn't worth it and there is a better solution that could be pursued instead.</p>
</blockquote>
<p>This is the only thing I worry about. While I agree that <code>Compatible&lt;T&gt;</code> is probably the most appealing approach, it does rely on a bit of faith that the implementation is possible.</p>



<a name="183643216"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183643216" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183643216">(Dec 17 2019 at 12:24)</a>:</h4>
<p>But I think we encode that in the alternatives section of the RFC. I personally am not familiar enough with rustc development to have an opinion here</p>



<a name="183660735"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183660735" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183660735">(Dec 17 2019 at 15:49)</a>:</h4>
<p>After doing some thinking I think it would be best if we kept Compatible as an unstable Feature and just implemented FromAnyBytes and ToBytes in terms of it. That way we don't have to 1000% sure about compatible before stabilizing the feature.</p>



<a name="183665280"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183665280" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183665280">(Dec 17 2019 at 16:32)</a>:</h4>
<p>I think that all changes being zero cost isn't a realistic goal in the first place.</p>



<a name="183742427"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183742427" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183742427">(Dec 18 2019 at 11:38)</a>:</h4>
<p>I think that having changes be zero-cost AND have a cheap type-level compilation overhead is indeed overly optimistic: we may indeed be able to move many checks to const / compile-time through derives, marker traits, and const_asserts, but so doing will impact compile-time, especially the derives. Imho the benefits (safe, quasi-zero-cost type punning) would clearly outweigh such cost, but it is something to be aware of.</p>
<p>(by the way I'd love to contribute to this project <span aria-label="slight smile" class="emoji emoji-1f642" role="img" title="slight smile">:slight_smile:</span>)</p>



<a name="183759128"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183759128" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183759128">(Dec 18 2019 at 15:21)</a>:</h4>
<p><span class="user-mention" data-user-id="224872">@Ryan Levick</span> so one thing i'm not sure how well it would work with <code>FromAnyBytes</code> and <code>ToBytes</code> is packed SIMD vectors.</p>



<a name="183759435"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183759435" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183759435">(Dec 18 2019 at 15:24)</a>:</h4>
<p>Can you expand on this?</p>



<a name="183759460"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183759460" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183759460">(Dec 18 2019 at 15:24)</a>:</h4>
<p>I can see the use case of going from <code>&amp;__m128</code> to <code>&amp;__m128d</code> when working with slices, but often one loads data, e.g., from a slice, into SIMD vectors on the stack, and then one needs to "transmute" <code>__m128</code> to <code>__m128d</code>.</p>



<a name="183759625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183759625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183759625">(Dec 18 2019 at 15:26)</a>:</h4>
<p>For this later use case, it is kind of weird to have to create a <code>&amp;__m128</code> to the stack (feels like a reference to a register), then transmute that into a <code>&amp;__m128d</code>, and then load from it, which creates a copy.</p>



<a name="183759836"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183759836" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183759836">(Dec 18 2019 at 15:28)</a>:</h4>
<p>Does that make sense?</p>



<a name="183759881"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183759881" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183759881">(Dec 18 2019 at 15:29)</a>:</h4>
<p>I'm not sure I fully understand. It sounds like you're saying you don't believe the current proposal handles "owned to owned" casting. Is that what you mean?</p>



<a name="183759955"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183759955" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183759955">(Dec 18 2019 at 15:30)</a>:</h4>
<p>Yes, thanks, that's a much better way to put it.</p>



<a name="183760032"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183760032" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183760032">(Dec 18 2019 at 15:31)</a>:</h4>
<p>The main use case of the FromBits/IntoBits proposal was SIMD, and for that use case, "owned to owned" feels more idiomatic.</p>



<a name="183760044"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183760044" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183760044">(Dec 18 2019 at 15:31)</a>:</h4>
<p>I believe it should. There should be a <code>cast_into</code>method in addition to the other casts.</p>



<a name="183760136"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183760136" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183760136">(Dec 18 2019 at 15:32)</a>:</h4>
<p>Oh, I don't recall seeing <code>cast_into</code> in the v2</p>



<a name="183760177"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183760177" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183760177">(Dec 18 2019 at 15:32)</a>:</h4>
<p>Is it new in the repo ?</p>



<a name="183760360"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183760360" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183760360">(Dec 18 2019 at 15:34)</a>:</h4>
<p>It was removed in the v2 proposal when Josh posted it, and I'm not sure why. I've added back on the RFC draft I'm working on now. I haven't push that work to the repo yet unfortunately. I need to ask Josh if that was on purpose, and if so, why.</p>



<a name="183760376"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183760376" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183760376">(Dec 18 2019 at 15:34)</a>:</h4>
<p>Ah ok, thanks, i'll check the v1 version.</p>



<a name="183762732"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183762732" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183762732">(Dec 18 2019 at 15:57)</a>:</h4>
<p><span class="user-mention" data-user-id="132920">@gnzlbg</span> one question I never got answered about <code>Compatible</code> is how it interacts with the orphan rule. If I have a type <code>B</code> and some other crates has type <code>A</code> and I want to express that it is safe to read <code>B</code> when you have a <code>A</code> (and perhaps not the other way around), how do you encode this? I don't believe it would be possible to <code>impl Compatible&lt;B&gt; for A</code> because type <code>A</code> lives outside your crate.</p>



<a name="183763505"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183763505" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183763505">(Dec 18 2019 at 16:05)</a>:</h4>
<p>Yes good question. I think the orphan rules allow <code>impl Compatible&lt;A&gt; for B</code> but i'm not sure if <code>impl Compatible&lt;B&gt; for A</code> is allowed</p>



<a name="183763544"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183763544" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183763544">(Dec 18 2019 at 16:05)</a>:</h4>
<p>Probably not, since <code>Compatible</code> is outside your crate, and so is A.</p>



<a name="183763624"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183763624" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183763624">(Dec 18 2019 at 16:06)</a>:</h4>
<p>Yes the first is allowed because the current crate "owns" that type, but the second is not allowed I believe. <br>
Is this a deal breaker? Seems pretty serious to me</p>



<a name="183763625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183763625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183763625">(Dec 18 2019 at 16:06)</a>:</h4>
<p>I'm not sure if it is possible to relax the orphan ruls to allow that impl, but I recall there were proposals to relax the orphan rules in directions similar to this (e.g. for <code>impl From&lt;B&gt; for A</code> maybe?)</p>



<a name="183763651"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183763651" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183763651">(Dec 18 2019 at 16:07)</a>:</h4>
<p>It's definetely not good, and i'm not sure if it is a deal breaker.</p>



<a name="183763709"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183763709" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183763709">(Dec 18 2019 at 16:07)</a>:</h4>
<p>Simple example would be <code>impl Compatible&lt;B&gt; for [u8; size_of::&lt;B&gt;()]</code></p>



<a name="183763800"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183763800" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183763800">(Dec 18 2019 at 16:08)</a>:</h4>
<p>since the array type is outside all crates but libcore. It would be very bad if that can't work, since then nothing works. Nice catch.</p>



<a name="183763813"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183763813" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183763813">(Dec 18 2019 at 16:08)</a>:</h4>
<p>hehe but then we're back to using bytes as intermediary which is very similar to the "v2" proposal</p>



<a name="183763834"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183763834" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183763834">(Dec 18 2019 at 16:09)</a>:</h4>
<p>Nono, that array was just an example of some <code>A</code> type</p>



<a name="183763847"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183763847" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183763847">(Dec 18 2019 at 16:09)</a>:</h4>
<p>notice that <code>[u8; N]</code>, <code>[T]</code>, etc. are all declared in libcore</p>



<a name="183763857"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183763857" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183763857">(Dec 18 2019 at 16:09)</a>:</h4>
<p>so that's the crate they belong to</p>



<a name="183763905"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183763905" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183763905">(Dec 18 2019 at 16:09)</a>:</h4>
<p>So then we're back to needing to change the orphan rules to get Compatible&lt;T&gt; to work</p>



<a name="183763969"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183763969" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183763969">(Dec 18 2019 at 16:10)</a>:</h4>
<p>If you have a crate with a type <code>B</code>, and you want to express that <code>[u8; N]</code> can be constructed from <code>B</code>, then you need such an impl to work, and that's somehting everybody has to be able to impl</p>



<a name="183763985"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183763985" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183763985">(Dec 18 2019 at 16:10)</a>:</h4>
<p><span class="user-mention" data-user-id="224872">@Ryan Levick</span> are you sure that you need to change the orphan rules for that ?</p>



<a name="183763994"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183763994" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183763994">(Dec 18 2019 at 16:10)</a>:</h4>
<p>E.g. does <code>impl From&lt;B&gt; for </code>u8` do not work ?</p>



<a name="183764051"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183764051" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183764051">(Dec 18 2019 at 16:11)</a>:</h4>
<p>IIRC the "trait" isn't <code>From</code>, but ""<code>From&lt;B&gt;</code>"", and since <code>B</code> is defined in your crate, then <code>From&lt;B&gt;</code> is kind of like defined in your crate as well, so you are like implementing a trait from your crate to an external type, and that does not violate orphan rules.</p>



<a name="183764081"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183764081" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183764081">(Dec 18 2019 at 16:11)</a>:</h4>
<p>Let me check if I can find that</p>



<a name="183764160"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183764160" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183764160">(Dec 18 2019 at 16:12)</a>:</h4>
<p>Yeah, see this issue: <a href="https://github.com/rust-lang/rfcs/issues/1856" target="_blank" title="https://github.com/rust-lang/rfcs/issues/1856">https://github.com/rust-lang/rfcs/issues/1856</a></p>



<a name="183764216"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183764216" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183764216">(Dec 18 2019 at 16:13)</a>:</h4>
<p>And this RFC: <a href="https://github.com/rust-lang/rfcs/pull/2451" target="_blank" title="https://github.com/rust-lang/rfcs/pull/2451">https://github.com/rust-lang/rfcs/pull/2451</a></p>



<a name="183764239"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183764239" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183764239">(Dec 18 2019 at 16:13)</a>:</h4>
<blockquote>
<p>More concretely, it allows impl&lt;T&gt; ForeignTrait&lt;LocalType&gt; for ForeignType&lt;T&gt; to be written.</p>
</blockquote>



<a name="183764362"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183764362" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183764362">(Dec 18 2019 at 16:14)</a>:</h4>
<blockquote>
<p>For example, impl From&lt;Foo&gt; for Vec&lt;i32&gt; is something any crate can write, even though From is a foreign trait, and Vec is a foreign type.</p>
</blockquote>



<a name="183764378"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183764378" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183764378">(Dec 18 2019 at 16:14)</a>:</h4>
<p>So it appears that this was allowed even before that RFC</p>



<a name="183764396"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183764396" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183764396">(Dec 18 2019 at 16:14)</a>:</h4>
<p>That RFC extended that to the <code>impl&lt;T&gt;</code> case</p>



<a name="183764426"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183764426" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183764426">(Dec 18 2019 at 16:14)</a>:</h4>
<p>Ah ok then maybe we don't have a problem</p>



<a name="183764448"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183764448" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183764448">(Dec 18 2019 at 16:15)</a>:</h4>
<p>I think that if this is a problem, then it would be kind of a killer</p>



<a name="183764768"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183764768" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183764768">(Dec 18 2019 at 16:18)</a>:</h4>
<p>This does bring up the issue that new types cannot help you if a piece of your Compatible type is a foreign type and it does not impl Compatible</p>



<a name="183783514"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183783514" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183783514">(Dec 18 2019 at 19:44)</a>:</h4>
<p>Why would you load data as <code>__m128</code> and then transmute to <code>__m128d</code>? There's functions to load directly into <code>__m128d</code> already.</p>



<a name="183784107"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183784107" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183784107">(Dec 18 2019 at 19:50)</a>:</h4>
<p>As to orphaning, I know that in <code>beryllium</code> I've written impls like</p>
<div class="codehilite"><pre><span></span><span class="k">impl</span><span class="w"> </span><span class="n">core</span>::<span class="nb">From</span><span class="o">&lt;</span><span class="n">beryllium</span>::<span class="n">ControllerAxisEvent</span><span class="o">&gt;</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">fermium</span>::<span class="n">SDL_ControllerAxisEvent</span><span class="w"></span>
</pre></div>


<p>(not quite real, I'm putting the crate origin in front of each type for clarity)</p>
<p>So in this case I'm using another crate's trait (core) and <em>for</em> another crate's type (fermium), but since the generic of the other crate's trait is a type from my own crate (beryllium), the overall instance is mine to write or not.</p>



<a name="183784654"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183784654" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183784654">(Dec 18 2019 at 19:56)</a>:</h4>
<p>So anyone defining their own type should be able to similarly write <code>impl Compatible&lt;MyType&gt; for [u8; 4]</code> or whatever.</p>



<a name="183830545"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183830545" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183830545">(Dec 19 2019 at 09:52)</a>:</h4>
<blockquote>
<p>Why would you load data as __m128 and then transmute to __m128d? </p>
</blockquote>
<p>Some intrinsics accept one type and not the other.</p>



<a name="183830563"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183830563" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183830563">(Dec 19 2019 at 09:53)</a>:</h4>
<p>So you need to go from one to the other somehow.</p>



<a name="183830598"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183830598" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183830598">(Dec 19 2019 at 09:53)</a>:</h4>
<blockquote>
<p>This does bring up the issue that new types cannot help you if a piece of your Compatible type is a foreign type and it does not impl Compatible</p>
</blockquote>
<p>Do you have an example of what you mean ?</p>



<a name="183865895"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183865895" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183865895">(Dec 19 2019 at 17:20)</a>:</h4>
<p><span class="user-mention" data-user-id="132920">@gnzlbg</span> there's intrinsics for those conversions, and probably they will perform better than whatever cast mechanism we make.</p>
<p>I don't mean to say that they shouldn't be supported by a casting API, but just that a casting API is the fallback case already.</p>



<a name="183866364"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/changes%20to%20pre-RFC%20proposal/near/183866364" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/changes.20to.20pre-RFC.20proposal.html#183866364">(Dec 19 2019 at 17:26)</a>:</h4>
<p>Care to elaborate? Those intrinsics just call transmute, the transmutes are safe, so a safe transmute API should be able to perform them if it aims to be complete , which his one of the constraints mentioned.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>